package com.example.chengbangming.chomeapp.utils;

import android.content.Context;
import android.content.res.AssetManager;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;

public class FileUtil {

    /**
     * 检查文件是否存在
     */
    public static boolean existsFile(String pathStr, String fileName) {
        try {
            File file = new File(pathStr, fileName);
            if (file.exists()) {
                return true;
            } else {
                return false;
            }
        } catch (Exception ex) {

        }
        return false;
    }

    /** 
     *  根据路径删除指定的目录或文件，无论存在与否 
     *@param sPath  要删除的目录或文件 
     *@return 删除成功返回 true，否则返回 false。 
     */  
    public static boolean DeleteFolder(String sPath) {
        boolean flag = false;  
        File file = new File(sPath);
        // 判断目录或文件是否存在  
        if (!file.exists()) {  // 不存在返回 false  
            return flag;  
        } else {  
            // 判断是否为文件  
            if (file.isFile()) {  // 为文件时调用删除文件方法  
                return deleteFile(sPath);  
            } else {  // 为目录时调用删除目录方法  
                return deleteDirectory(sPath);  
            }  
        }  
    }  
    
    /** 
     * 删除单个文件 
     * @param   sPath    被删除文件的文件名 
     * @return 单个文件删除成功返回true，否则返回false 
     */  
    private static boolean deleteFile(String sPath) {
        boolean flag = false;  
//        if(sPath.equals(constdef.CODE_ROLE_DIR)){
//        	//不删除正则文件
//        	flag = true;
//        }else{
        	File file = new File(sPath);
            // 路径为文件且不为空则进行删除  
            if (file.isFile() && file.exists()) {  
                file.delete();  
                flag = true;  
            } 
//        }
         
        return flag;  
    }  
    
    /** 
     * 删除目录（文件夹）以及目录下的文件 
     * @param   sPath 被删除目录的文件路径 
     * @return  目录删除成功返回true，否则返回false 
     */  
    private static boolean deleteDirectory(String sPath) {
        //如果sPath不以文件分隔符结尾，自动添加文件分隔符  
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }  
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在，或者不是一个目录，则退出  
        if (!dirFile.exists() || !dirFile.isDirectory()) {  
            return false;  
        }  
        boolean flag = true;  
        //删除文件夹下的所有文件(包括子目录)  
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {  
            //删除子文件  
            if (files[i].isFile()) {  
                flag = deleteFile(files[i].getAbsolutePath());  
                if (!flag) break;  
            } //删除子目录  
            else {  
                flag = deleteDirectory(files[i].getAbsolutePath());  
                if (!flag) break;  
            }  
        }  
        if (!flag) return false;  
//        //删除当前目录  
//        if (dirFile.delete()) {  
//            return true;  
//        } else {  
//            return false;  
//        }  
        return true;
    }  
    
    
    /**
     * 写， 读sdcard目录上的文件，要用FileOutputStream， 不能用openFileOutput
     * 不同点：openFileOutput是在raw里编译过的，FileOutputStream是任何文件都可以
     * @param fileName
     * @param message
     */ 
    // 写在/mnt/sdcard/目录下面的文件 
    public static void writeFileSdcard(String fileName, String message) {
 
        try { 
 
            // FileOutputStream fout = openFileOutput(fileName, MODE_PRIVATE); 
 
            FileOutputStream fout = new FileOutputStream(fileName);
 
            byte[] bytes = message.getBytes(); 
 
            fout.write(bytes); 
 
            fout.close(); 
 
        } 
 
        catch (Exception e) {
 
            e.printStackTrace(); 
 
        }
 
    } 
 
    // 读在/mnt/sdcard/目录下面的文件 
 
    public static String readFileSdcard(String fileName) {
 
        String res = "";
 
        try { 
 
            FileInputStream fin = new FileInputStream(fileName);
 
            int length = fin.available(); 
 
            byte[] buffer = new byte[length]; 
 
            fin.read(buffer); 
 
//            res = EncodingUtils.getString(buffer, "UTF-8");
            res = new String(buffer,"UTF-8");
 
            fin.close(); 
 
        } 
 
        catch (Exception e) {
 
            e.printStackTrace(); 
 
        } 
 
        return res; 
 
    } 
    
    //复制assets下文件到指定sd卡位置
    public static boolean copyAssetsToFilesystem(Context context, String assetsSrc, String sdDes){
        InputStream istream = null;
        OutputStream ostream = null;
        try{  
            AssetManager am = context.getAssets();
            istream = am.open(assetsSrc);  
            ostream = new FileOutputStream(sdDes);
            byte[] buffer = new byte[1024];  
            int length;  
            while ((length = istream.read(buffer))>0){  
                ostream.write(buffer, 0, length);  
            }  
            istream.close();  
            ostream.close();  
        }  
        catch(Exception e){
            e.printStackTrace();  
            try{  
                if(istream!=null)  
                    istream.close();  
                if(ostream!=null)  
                    ostream.close();  
            }  
            catch(Exception ee){
                ee.printStackTrace();  
            }  
            return false;  
        }  
        return true;  
    }

    public static boolean createPath(String path){
        // 如果要保存的路径不存在则创建路径
        File dir = new File(path);
        if (!dir.exists()) {
            try {
                dir.mkdir();
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    /**
     * 复制 Handler 要执行的操作， frompath从什么地方复制， topath复制到什么地方，
     * isreplace如果复制到的地方文件已存在是否覆盖， isdelole是否复制完成后删除原来的文件
     */
    public static boolean doCopy(Handler handler, String fromPath, String toPath,
                                 String fileName, Boolean isReplace, Boolean isDelOle) {
        boolean isFinish = true;
        try {
            // 如果要拷贝的对象不存在 返回true 并不继续进行操作
            File fromFile = new File(fromPath, fileName);
            if (!fromFile.exists()) {
                return true;
            }

            // 如果要保存的路径不存在则创建路径
            File dir = new File(toPath);
            if (!dir.exists()) {
                try {
                    dir.mkdir();
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            // 如果保存的路径下已经存在被拷贝对象 判断是否需要替换掉
            File toFile = new File(dir, fileName);
            if (toFile.exists()) {
                if (isReplace) {
                    toFile.delete();
                } else {
                    return true;
                }
            }
            toFile.createNewFile();
            InputStream in = new FileInputStream(fromFile);
            int size = in.available(); // 文件大小
            int bytesum = 0;// 已完成大小
            int byteread = 0;// 每次读取的大小
            byte[] buffer = new byte[1024]; // 每次可读取的最大值
            FileOutputStream out = new FileOutputStream(toFile);
            while ((byteread = in.read(buffer)) != -1) {
                bytesum += byteread; // 字节数 文件大小
                out.write(buffer, 0, byteread);
                if (handler != null) {
                    double ratioDou = Double.parseDouble(MathUtil.getPercent(
                            bytesum, size, "0.00")) * 100;
                    Message message = new Message();
                    message.what = 0;
                    message.obj = (int) ratioDou;
                    handler.sendMessage(message);
                }
            }
            out.flush();
            out.close();
            in.close();
            if (isDelOle) {
                fromFile.delete();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            isFinish = false;
        }
        return isFinish;
    }

    /**
     * 复制 Handler 要执行的操作， frompath从什么地方复制， topath复制到什么地方，
     * isreplace如果复制到的地方文件已存在是否覆盖， isdelole是否复制完成后删除原来的文件
     */
    public static boolean doCopyAssets(Context context, Handler handler, String assetsFileName, String toPath,
                                       String fileName, Boolean isReplace) {
        boolean isFinish = true;
        try {
            // 如果要拷贝的对象不存在 返回true 并不继续进行操作
//            File fromFile = new File(fromPath, fileName);
//            if (!fromFile.exists()) {
//                return true;
//            }
            if(StringUtil.isEmpty(assetsFileName)){
                return true;
            }

            // 如果要保存的路径不存在则创建路径
            File dir = new File(toPath);
            if (!dir.exists()) {
                try {
                    dir.mkdir();
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

            // 如果保存的路径下已经存在被拷贝对象 判断是否需要替换掉
            File toFile = new File(dir, fileName);
            if (toFile.exists()) {
                if (isReplace) {
                    toFile.delete();
                } else {
                    return true;
                }
            }
            toFile.createNewFile();
            InputStream in = context.getAssets().open(assetsFileName);
            int size = in.available(); // 文件大小
            int bytesum = 0;// 已完成大小
            int byteread = 0;// 每次读取的大小
            byte[] buffer = new byte[1024]; // 每次可读取的最大值
            FileOutputStream out = new FileOutputStream(toFile);
            while ((byteread = in.read(buffer)) != -1) {
                bytesum += byteread; // 字节数 文件大小
                out.write(buffer, 0, byteread);
                if (handler != null) {
                    double ratioDou = Double.parseDouble(MathUtil.getPercent(
                            bytesum, size, "0.00")) * 100;
                    Message message = new Message();
                    message.what = 0;
                    message.obj = (int) ratioDou;
                    handler.sendMessage(message);
                }
            }
            out.flush();
            out.close();
            in.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            isFinish = false;
        }
        return isFinish;
    }

    /**
     * 检测磁盘空间是否足够
     */
    public static boolean getAvailableStorage(long fileSize) {
        long avaliableSize;
        String storageDirectory = null;
        storageDirectory = Environment.getExternalStorageDirectory().toString();
        try {
            StatFs stat = new StatFs(storageDirectory);
            avaliableSize = ((long) stat.getAvailableBlocks() * (long) stat
                    .getBlockSize());
        } catch (Exception ex) {
            ex.printStackTrace();
            avaliableSize = 0;
        }
        if (avaliableSize < fileSize) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 文件分割读取
     */
    public class FileAccessI implements Serializable
    {

        int defSize = 1024000;//默认读取1024000字节

        RandomAccessFile oSavedFile;
        long nPos;

        public FileAccessI() throws IOException
        {
            this("", 0);
        }

        public FileAccessI(String sName, long nPos) throws IOException
        {
            oSavedFile = new RandomAccessFile(sName, "rw");//创建一个随机访问文件类，可读写模式
            this.nPos = nPos;
            oSavedFile.seek(nPos);
        }

        public FileAccessI(File sFile, long nPos) throws IOException
        {
            oSavedFile = new RandomAccessFile(sFile, "rw");//创建一个随机访问文件类，可读写模式
            this.nPos = nPos;
            oSavedFile.seek(nPos);
        }

        public synchronized int write(byte[] b, int nStart, int nLen)
        {
            int n = -1;
            try
            {
                oSavedFile.write(b, nStart, nLen);
                n = nLen;
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return n;
        }

        //每次读取指定字节数
        public synchronized Detail getContent(long nStart,int partSize)
        {
            if(partSize==0){
                partSize = defSize;
            }
            Detail detail = new Detail();
            detail.b = new byte[partSize];
            try
            {
                oSavedFile.seek(nStart);
                detail.length = oSavedFile.read(detail.b);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return detail;
        }

        //每次读取默认1024000字节数
        public synchronized Detail getContent(long nStart)
        {
            Detail detail = new Detail();
            detail.b = new byte[defSize];
            try
            {
                oSavedFile.seek(nStart);
                detail.length = oSavedFile.read(detail.b);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return detail;
        }


        public class Detail
        {

            public byte[] b;
            public int length;
        }

        //获取文件长度
        public long getFileLength()
        {
            Long length = 0l;
            try
            {
                length = oSavedFile.length();
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return length;
        }
    }
}
